<?php

    /**
     * This file is part of the Intelligencer package.
     * For the full copyright and license, please view the LICENSE
     * file that was distributed with this source code.
     * 
     * @author      drapeko <roman.drapeko@gmail.com>
     * @copyright   Roman Drapeko <roman.drapeko@gmail.com>, 2009 - present
     */

    /**
     * Simple template idea is to replace variables in the path by the exact values and provide TemplateIntelligencer a list
     * of possible pathes.
     * 
     * namespace, class, lowernamespace, lowerclass are predefined variables that can be used without passing any values.
     * 
     * For example 
     * <code> 
     * $template = new itSimpleTemplate();
     * $template->setPrefix('C:/project/')->setVariables(array('extension' => array('php', 'class.php')))->setTemplate('%class%.%extension%');
     * $template->getPath('Class');
     * </code>
     * 
     * The above template is valid for: C:/project/Class.php and C:/project/Class.class.php
     * 
     * @author drapeko
     */
    class itSimpleTemplate extends itTemplate {
        
        const VAR_NAMESPACE = '%namespace%';
        const VAR_CLASS = '%class%';
        const VAR_LOWER_NAMESPACE = '%lowernamespace%';
        const VAR_LOWER_CLASS = '%lowerclass%';
        
        protected $template = null;
        protected $preparedTemplates = array();
        protected $variables = array();
        protected $preparedVariables = array();
        protected $prefix = '';
        protected $prepared = false;
        
        /**
         * Constructor can accepts the template and an array of variables
         * 
         * Example
         * <code>
         * $simple = new itSimpleTemplate('/home/drapeko/%namespace%/%class%.%ext%', array('ext' => array('php', 'class.php')));
         * </code>
         * 
         * @param string $template null
         * @param array $variables array()
         */
        public function __construct($template = null, array $variables = array()) {
            $this->template = $template;
            $this->variables = $this->preVariables($variables);
            if (!empty($template) && !empty($variables)) {
                $this->prepare();
            }
        }
        
        protected function preVariables(array $variables = array()) {
            $result = array();
            foreach($variables as $k => $v) {
                $result[$k] = (array)$v;
            }
            return $result;
        }
        
        /**
         * Sets the prefix to the path (path base)
         * @param string $prefix
         * @return itTemplate itself
         */
        public function setPrefix($prefix = '') {
            $this->prefix = $prefix;
            return $this;
        }
        
        /**
         * Returns the prefix
         * @return string
         */
        public function getPrefix() {
            return $this->prefix;
        }
        
        protected function prepare() {
            $this->preparedTemplates = array();
            $this->preparedVariables = array();
            
            if (count($this->variables) > 0) {
                foreach($this->variables as $key => $val) {
                    $this->preparedVariables['%'.$key.'%'] = $val;
                }
                
                $productions = itUtil::arrayCartesianKeys($this->preparedVariables);
                foreach($productions as $prod) {
                    $this->preparedTemplates[] = strtr($this->prefix.$this->template, $prod);
                }
            } else {
                $this->preparedTemplates[] = $this->prefix.$this->template;
            }
            
            $this->prepared = true;
        }
        
        /**
         * Sets the template string. 
         * 
         * Example 
         * <code>
         * $t = new itSimpleTemplate();
         * $t->setTemplate('/home/drapeko/%namespace%/%class%.%ext%')
         * </code>
         * 
         * Variables are marked with '%' from both sides.
         * 
         * @return itTemplate itself
         */
        public function setTemplate($template) {
            $this->template = $template;
            $this->prepared = false;
            return $this;
        }
        
        /**
         * Returns the template string
         * @return string
         */
        public function getTemplate() {
            return $this->template;
        }
        
        /**
         * Sets the array of user variables
         * Example
         * <code>
         *  $t->setVariables(array(
         *      'ext' => array('php, 'txt'),
         *      'dir' => array('Project1', 'Project2')
         *  ));
         * </code>
         * @param array $variables
         * @return itTemplate itself
         */
        public function setVariables(array $variables) {
            $this->variables = $variables;
            $this->prepared = false;
            return $this;
        }
        
        /**
         * Returns the user defiend variables
         * @return array
         */
        public function getVariables() {
            return $this->variables;
        }
        
        /**
         * Returns an array of possible locations according to the className and user defined variables
         * @param string $className
         * @return string
         */
        public function getPath($className) {
            if (!$this->prepared) {
                $this->prepare();
            }
            list($namespace, $class) = itUtil::getClassAndNS($className);
            list($lower_namespace, $lower_class) = array(strtolower($namespace), strtolower($class));
            
            $translate = array (
                self::VAR_NAMESPACE => $namespace,
                self::VAR_CLASS => $class,
                self::VAR_LOWER_NAMESPACE => $lower_namespace,
                self::VAR_LOWER_CLASS => $lower_class
            );
            
            $return = array();
            foreach($this->preparedTemplates as $t) {
                $return[] = strtr($t, $translate);
            }
            
            return $return;
        }
    }

?>